package com.fiveChess;

import android.content.ContentResolver;
import android.content.ContentUris;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.net.Uri;
import android.os.Parcel;
import android.os.Parcelable;
import android.provider.BaseColumns;

public final class Game implements Parcelable {
	
	public static final String TABLE_NAME = "games";
	
	public int id;
	private long time;
	private String content;
	private boolean ended;
	
	public static final Parcelable.Creator<Game> CREATOR = new Parcelable.Creator<Game>() {
		public Game createFromParcel(Parcel p) {
			return new Game(p);
		}

		@Override
		public Game[] newArray(int size) {
			return new Game[size];
		}

	};
	
	public int describeContents() {
		return 5;
	}

	public void writeToParcel(Parcel p, int flags) {
		p.writeInt(id);
		p.writeString(getContent());
		p.writeLong(getTime());
		p.writeInt(ended ? 1 : 0);
		p.writeInt(isBlack ? 1 : 0);
	}


	

	public boolean isEnded() {
		return ended;
	}

	public void setEnded(boolean ended) {
		this.ended = ended;
	}

	public boolean isBlack() {
		return isBlack;
	}

	public void setBlack(boolean isBlack) {
		this.isBlack = isBlack;
	}

	private boolean isBlack;

	public Game(Cursor c) {
		id = c.getInt(Columns.GAME_ID_INDEX);
		setTime(c.getLong(Columns.GAME_TIME_LAST_PLAY_INDEX));
		setContent(c.getString(Columns.GAME_CONTENT_INDEX));
		ended = c.getInt(Columns.GAME_ENDED_INDEX) == 1;
		isBlack = c.getInt(Columns.GAME_ISBLACK_INDEX) == 1;
	}

	public Game(Parcel p) {
		id = p.readInt();
		setTime(p.readLong());
		setContent(p.readString());
		ended = p.readInt() == 1;
		isBlack = p.readInt() == 1;
	}
	
	public Game() {
		id = -1;
		setContent("");
		setTime(0);
		ended = false;
		isBlack = true;
	}
	
	public String getContent() {
		return content;
	}

	public void setContent(String content) {
		this.content = content;
	}

	public long getTime() {
		return time;
	}

	public void setTime(long time) {
		this.time = time;
	}

	// list of Games.
	public static final String Game_ID = "game_id";

	/**
	 * Creates a new Game and fills in the given game's id.
	 */
	public static void addGame(Context context, Game game) {
		ContentValues values = createContentValues(game);
		Uri uri = context.getContentResolver().insert(Game.Columns.CONTENT_URI,
				values);
		game.id = (int) ContentUris.parseId(uri);
	}

	/**
	 * A convenience method to set an game in the Games content provider.
	 * 
	 * @return Time when the Game will fire.
	 */
	public static void setGame(Context context, Game game) {
		ContentValues values = createContentValues(game);
		ContentResolver resolver = context.getContentResolver();
		resolver.update(
				ContentUris.withAppendedId(Game.Columns.CONTENT_URI, game.id),
				values, null, null);
	}

	/**
	 * Removes an existing Game. If this Game is snoozing, disables snooze. Sets
	 * next alert.
	 */
	public static void deleteGame(Context context, int gameId) {
		if (gameId == -1)
			return;
		ContentResolver contentResolver = context.getContentResolver();
		Uri uri = ContentUris.withAppendedId(Game.Columns.CONTENT_URI, gameId);
		contentResolver.delete(uri, "", null);
	}

	/**
	 * Queries all Games
	 * 
	 * @return cursor over all Games
	 */
	public static Cursor getGamesCursor(ContentResolver contentResolver) {
		return contentResolver.query(Game.Columns.CONTENT_URI,
				Game.Columns.GAME_QUERY_COLUMNS, null, null,
				Game.Columns.DEFAULT_SORT_ORDER);
	}

	/**
	 * to get unfinished set of Games from the database.
	 */
	public static Cursor getFilteredGamesCursor(ContentResolver contentResolver) {
		return contentResolver.query(Game.Columns.CONTENT_URI,
				Game.Columns.GAME_QUERY_COLUMNS, Game.Columns.WHERE_ENABLED,
				null, null);
	}

	private static ContentValues createContentValues(Game game) {
		ContentValues values = new ContentValues(4);
		// Set the Game_time value if this Game does not repeat. This will be
		// used later to disable expire Games.
		values.put(Game.Columns.CONTENT_GAME_CONTENT, game.getContent());
		values.put(Game.Columns.CONTENT_TIME, game.getTime());
		values.put(Game.Columns.CONTENT_ENDED, game.isEnded() ? 1 : 0);
		values.put(Game.Columns.CONTENT_ISBLACK, game.isBlack() ? 1 : 0);
		return values;
	}

	/**
	 * Return an Game object representing the Game id in the database. Returns
	 * null if no Game exists.
	 */
	public static Game getGame(ContentResolver contentResolver, int gameId) {
		Cursor cursor = contentResolver.query(
				ContentUris.withAppendedId(Game.Columns.CONTENT_URI, gameId),
				Game.Columns.GAME_QUERY_COLUMNS, null, null, null);
		Game game = null;
		if (cursor != null) {
			if (cursor.moveToFirst()) {
				game = new Game(cursor);
			}
			cursor.close();
		}
		return game;
	}
	
	@Override
	public String toString() {
		System.err.println("game:" + this.getTime());
		System.err.println("game isBlack:" + this.isBlack());
		System.err.println("game isEnded:" + this.isEnded());
		return super.toString();
	}
	
	public static class Columns implements BaseColumns {
		/**
		 */
		public static final Uri CONTENT_URI = Uri
				.parse("content://com.fiveChess/game");
		
		public static final String CONTENT_GAME_CONTENT = "game_content";
		/**
		 * The last time Game play Note: not currently used
		 * <P>
		 * Type: STRING
		 * </P>
		 */
		public static final String CONTENT_TIME = "time";
		/**
		 * While the game is ended Note: not currently used
		 * <P>
		 * Type: STRING
		 * </P>
		 */
		public static final String CONTENT_ENDED = "ended";
		
		/**
		 * While the game is ended Note: not currently used
		 * <P>
		 * Type: STRING
		 * </P>
		 */
		public static final String CONTENT_ISBLACK = "isBlack";
		/**
		 * The default sort order for this table
		 */
		public static final String DEFAULT_SORT_ORDER = CONTENT_TIME + " ASC";
		
		/**
		 * The Game still not finished
		 */
		public static final String WHERE_ENABLED = CONTENT_ENDED + "=0";
		
		static final String[] GAME_QUERY_COLUMNS = { _ID, CONTENT_GAME_CONTENT,
			CONTENT_TIME, CONTENT_ENDED, CONTENT_ISBLACK };
		
		/**
		 * These save calls to cursor.getColumnIndexOrThrow() THEY MUST BE KEPT
		 * IN SYNC WITH ABOVE QUERY COLUMNS
		 */
		public static final int GAME_ID_INDEX = 0;
		public static final int GAME_CONTENT_INDEX = 1;
		public static final int GAME_TIME_LAST_PLAY_INDEX = 2;
		public static final int GAME_ENDED_INDEX = 3;
		public static final int GAME_ISBLACK_INDEX = 4;
	}
}
